package com.isoft.airportsystem.interceptor;

import com.fasterxml.jackson.databind.ObjectMapper;
import com.isoft.airportsystem.annotation.RequiresPermission;
import com.isoft.airportsystem.common.Result;
import com.isoft.airportsystem.service.system.UserService;
import com.isoft.airportsystem.util.JwtUtil;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.springframework.util.StringUtils;
import org.springframework.web.method.HandlerMethod;
import org.springframework.web.servlet.HandlerInterceptor;

import java.io.IOException;
import java.util.List;

/**
 * 权限拦截器
 */
@Slf4j
@Component
public class PermissionInterceptor implements HandlerInterceptor {

    @Autowired
    private JwtUtil jwtUtil;

    @Autowired
    private UserService userService;

    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
        // 如果不是方法处理器，直接放行
        if (!(handler instanceof HandlerMethod)) {
            return true;
        }

        HandlerMethod handlerMethod = (HandlerMethod) handler;

        // 检查是否有权限注解
        RequiresPermission methodPermission = handlerMethod.getMethodAnnotation(RequiresPermission.class);
        RequiresPermission classPermission = handlerMethod.getBeanType().getAnnotation(RequiresPermission.class);

        // 如果没有权限注解，直接放行
        if (methodPermission == null && classPermission == null) {
            return true;
        }

        // 获取Token
        String token = getTokenFromRequest(request);
        if (!StringUtils.hasText(token)) {
            handleUnauthorized(response, "未提供认证Token");
            return false;
        }

        // 验证Token
        if (!jwtUtil.validateToken(token)) {
            handleUnauthorized(response, "Token无效或已过期");
            return false;
        }

        // 获取用户权限
        Long userId = jwtUtil.getUserIdFromToken(token);
        List<String> userPermissions = userService.selectPermissionsByUserId(userId);

        // 检查权限
        boolean hasPermission = checkPermission(methodPermission, classPermission, userPermissions);
        if (!hasPermission) {
            handleForbidden(response, "权限不足");
            return false;
        }

        return true;
    }

    /**
     * 从请求中获取Token
     */
    private String getTokenFromRequest(HttpServletRequest request) {
        // 从请求头获取
        String token = request.getHeader("Authorization");
        if (StringUtils.hasText(token) && token.startsWith("Bearer ")) {
            return token.substring(7);
        }

        // 从请求参数获取
        token = request.getParameter("token");
        if (StringUtils.hasText(token)) {
            return token;
        }

        return null;
    }

    /**
     * 检查权限
     */
    private boolean checkPermission(RequiresPermission methodPermission, RequiresPermission classPermission, List<String> userPermissions) {
        // 优先使用方法级别的权限注解
        RequiresPermission permission = methodPermission != null ? methodPermission : classPermission;
        if (permission == null) {
            return true;
        }

        String requiredPermission = permission.value();

        if (permission.requireAll()) {
            // 需要所有权限
            String[] permissions = requiredPermission.split(",");
            for (String perm : permissions) {
                if (!userPermissions.contains(perm.trim())) {
                    return false;
                }
            }
            return true;
        } else {
            // 只需要其中一个权限
            String[] permissions = requiredPermission.split(",");
            for (String perm : permissions) {
                if (userPermissions.contains(perm.trim())) {
                    return true;
                }
            }
            return false;
        }
    }

    /**
     * 处理未授权响应
     */
    private void handleUnauthorized(HttpServletResponse response, String message) throws IOException {
        response.setStatus(HttpServletResponse.SC_UNAUTHORIZED);
        response.setContentType("application/json;charset=UTF-8");

        Result<?> result = Result.error(401, message);
        ObjectMapper mapper = new ObjectMapper();
        response.getWriter().write(mapper.writeValueAsString(result));
    }

    /**
     * 处理禁止访问响应
     */
    private void handleForbidden(HttpServletResponse response, String message) throws IOException {
        response.setStatus(HttpServletResponse.SC_FORBIDDEN);
        response.setContentType("application/json;charset=UTF-8");

        Result<?> result = Result.error(403, message);
        ObjectMapper mapper = new ObjectMapper();
        response.getWriter().write(mapper.writeValueAsString(result));
    }
} 